#ifndef lint
static const char yysccsid[] = "@(#)yaccpar	1.9 (Berkeley) 02/21/93";
#endif

#include <stdlib.h>
#include <string.h>

#define YYBYACC 1
#define YYMAJOR 1
#define YYMINOR 9
#define YYPATCH 20070509

#define YYEMPTY (-1)
#define yyclearin    (yychar = YYEMPTY)
#define yyerrok      (yyerrflag = 0)
#define YYRECOVERING (yyerrflag != 0)

extern int yyparse(void);

static int yygrowstack(void);
#define yyparse studentsparse
#define yylex studentslex
#define yyerror studentserror
#define yychar studentschar
#define yyval studentsval
#define yylval studentslval
#define yydebug studentsdebug
#define yynerrs studentsnerrs
#define yyerrflag studentserrflag
#define yyss studentsss
#define yyssp studentsssp
#define yyvs studentsvs
#define yyvsp studentsvsp
#define yylhs studentslhs
#define yylen studentslen
#define yydefred studentsdefred
#define yydgoto studentsdgoto
#define yysindex studentssindex
#define yyrindex studentsrindex
#define yygindex studentsgindex
#define yytable studentstable
#define yycheck studentscheck
#define yyname studentsname
#define yyrule studentsrule
#define YYPREFIX "students"
#line 2 "parser.y"
# include "parser.h"

static ArrayList *result;
extern FILE *studentsin;
#line 8 "parser.y"
typedef union {
	char *string;
	float virgula;
	int number;
	LinkedList *list;
	Student *student;
	StudentType tipo;
} YYSTYPE;
#line 61 "st.tab.c"
#define STRING 257
#define DIGITS 258
#define FLOAT 259
#define NUMBER 260
#define LABEL_NAME 261
#define OPEN 262
#define CLOSE 263
#define EQUAL 264
#define STOP 265
#define LABEL_YEAR 266
#define LABEL_NORMAL 267
#define LABEL_EXTRA 268
#define LABEL_PRO 269
#define LABEL_CHOICES 270
#define LABEL_WANTED 271
#define LABEL_MEDIA 272
#define LABEL_TIPO 273
#define YYERRCODE 256
short studentslhs[] = {                                        -1,
    0,    0,    5,    5,    2,    3,    3,    3,    3,    3,
    3,    3,    4,    4,    4,    1,    1,
};
short studentslen[] = {                                         2,
    1,    0,    2,    1,    4,    5,    5,    5,    5,    5,
    5,    0,    1,    1,    1,    5,    0,
};
short studentsdefred[] = {                                      0,
    0,    0,    4,    0,   12,    3,    0,    0,    5,    0,
    0,    0,    0,    0,    0,    0,   17,    0,    0,    0,
    0,    0,    0,    0,    0,   13,   15,   14,    0,    6,
    9,    0,   11,   10,    7,    8,    0,    0,   16,
};
short studentsdgoto[] = {                                       2,
   23,    3,    7,   29,    4,
};
short studentssindex[] = {                                   -257,
 -258,    0,    0, -257,    0,    0, -261, -248,    0, -247,
 -244, -245, -243, -242, -251, -252,    0, -240, -237, -254,
 -241, -239, -256, -238, -236,    0,    0,    0, -235,    0,
    0, -233,    0,    0,    0,    0, -232, -231,    0,
};
short studentsrindex[] = {                                     25,
    0,    0,    0,   32,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,
};
short studentsgindex[] = {                                      0,
    0,   29,    0,    0,    0,
};
#define YYTABLESIZE 34
short studentstable[] = {                                       8,
   32,    9,    1,    5,   10,   21,   33,   22,   11,   12,
   13,   14,   26,   27,   28,   15,   16,   17,   18,   24,
   19,   20,   25,   30,    2,   31,   34,   38,   35,   36,
   37,    1,    6,   39,
};
short studentscheck[] = {                                     261,
  257,  263,  260,  262,  266,  257,  263,  260,  270,  271,
  272,  273,  267,  268,  269,  264,  264,  262,  264,  260,
  264,  264,  260,  265,    0,  265,  265,  260,  265,  265,
  264,    0,    4,  265,
};
#define YYFINAL 2
#ifndef YYDEBUG
#define YYDEBUG 0
#endif
#define YYMAXTOKEN 273
#if YYDEBUG
char *studentsname[] = {
"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"STRING","DIGITS","FLOAT",
"NUMBER","LABEL_NAME","OPEN","CLOSE","EQUAL","STOP","LABEL_YEAR","LABEL_NORMAL",
"LABEL_EXTRA","LABEL_PRO","LABEL_CHOICES","LABEL_WANTED","LABEL_MEDIA",
"LABEL_TIPO",
};
char *studentsrule[] = {
"$accept : Document",
"Document : Students",
"Document :",
"Students : Students Student",
"Students : Student",
"Student : NUMBER OPEN StudentDataList CLOSE",
"StudentDataList : StudentDataList LABEL_NAME EQUAL STRING STOP",
"StudentDataList : StudentDataList LABEL_MEDIA EQUAL NUMBER STOP",
"StudentDataList : StudentDataList LABEL_TIPO EQUAL StuType STOP",
"StudentDataList : StudentDataList LABEL_YEAR EQUAL NUMBER STOP",
"StudentDataList : StudentDataList LABEL_WANTED EQUAL NUMBER STOP",
"StudentDataList : StudentDataList LABEL_CHOICES OPEN StudentChoices CLOSE",
"StudentDataList :",
"StuType : LABEL_NORMAL",
"StuType : LABEL_PRO",
"StuType : LABEL_EXTRA",
"StudentChoices : StudentChoices STRING EQUAL NUMBER STOP",
"StudentChoices :",
};
#endif
#if YYDEBUG
#include <stdio.h>
#endif

/* define the initial stack-sizes */
#ifdef YYSTACKSIZE
#undef YYMAXDEPTH
#define YYMAXDEPTH  YYSTACKSIZE
#else
#ifdef YYMAXDEPTH
#define YYSTACKSIZE YYMAXDEPTH
#else
#define YYSTACKSIZE 500
#define YYMAXDEPTH  500
#endif
#endif

#define YYINITSTACKSIZE 500

int      yydebug;
int      yynerrs;
int      yyerrflag;
int      yychar;
short   *yyssp;
YYSTYPE *yyvsp;
YYSTYPE  yyval;
YYSTYPE  yylval;

/* variables for the parser stack */
static short   *yyss;
static short   *yysslim;
static YYSTYPE *yyvs;
static int      yystacksize;
#line 66 "parser.y"

static Student * insertType (Student *st, StudentType t) {
        if (!st) st = newStudent();
        st->type = t;
        return st;

}
static Student * insertWanted (Student *st, int t) {
        if (!st) st = newStudent();
        st->ucesWanted = t;
        return st;

}
static Student * insertChoices(Student *st, LinkedList *list) {
        if (!st) st = newStudent();
        st->selections = list;
        return st;
}

static Student * insertNumber(int number, Student *st) {
        if (!st) st = newStudent();
        st->number = number;
        return st;
}

static Student * insertAverage(Student *st, int avg) {
        if (!st) st = newStudent();
        st->average = avg;
        return st;
}

static Student * insertYear(Student *st, int year) {
        if (!st) st = newStudent();
        st->year = year;
        return st;
}

static void insertStudent (Student *st) {
	arrayInsert(result,st);
}
static Student * insertName(Student *st,char *name) {
	if (!st) st = newStudent();
	st->name = name;
	return st;
}
static LinkedList * insertChoice(LinkedList *old, char *uce, int pref) {
	Selection *s = newSelection(uce,pref);
	old = insertElemHead(old,s);
	return old;
}

/*int yywrap () {
	return 1;
}*/

int yyerror (char *err) {
	printf("%s\n",err);
	return 1;
}

ArrayList * readStudents (FILE *fp) {
	studentsin = fp;
	result = newArrayList(STUDENT_LIST_SIZE);
	if (yyparse()) {
		printf("ERRO\n");
		return NULL;
	}
	return result; 
}

void writeStudents (ArrayList *list, FILE *fp) {
	Student *st_aux;
	Selection *s_aux;
	LinkedList *tmp;
	int printChoises = 0;
	int i;
	for (i=0;i<arrayGetLength(list);i++) {
		st_aux = arrayGet(list,i);
		fprintf(fp,"%d {\n",st_aux->number);
		fprintf(fp,"\tNome = '%s';\n",st_aux->name);
		fprintf(fp,"\tAno = %d;\n",st_aux->year);
		fprintf(fp,"\tMedia = %d;\n",st_aux->average);
		fprintf(fp,"\tUces = %d;\n",st_aux->ucesWanted);
		switch (st_aux->type) {
			case NORMAL:
				fprintf(fp,"\tTipo = NORMAL;\n");
				break;
			case PROFESSIONAL:
				fprintf(fp,"\tTipo = PROFISSIONAL;\n");
				break;
			case EXTRA:
				fprintf(fp,"\tTipo = EXTRA;\n");
				break;
		}
		tmp = st_aux->selections;
		if (tmp) {
			fprintf(fp,"\tEscolhas {\n");
			while (tmp) {
				s_aux = getData(tmp);
				fprintf(fp,"\t\t'%s' = %d;\n",s_aux->uceName,s_aux->preference);
				tmp = tmp->next;
			}
			fprintf(fp,"\t}\n");
		}
		fprintf(fp,"}\n");
	}
}
#line 305 "st.tab.c"
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
static int yygrowstack(void)
{
    int newsize, i;
    short *newss;
    YYSTYPE *newvs;

    if ((newsize = yystacksize) == 0)
        newsize = YYINITSTACKSIZE;
    else if (newsize >= YYMAXDEPTH)
        return -1;
    else if ((newsize *= 2) > YYMAXDEPTH)
        newsize = YYMAXDEPTH;

    i = yyssp - yyss;
    newss = (yyss != 0)
          ? (short *)realloc(yyss, newsize * sizeof(*newss))
          : (short *)malloc(newsize * sizeof(*newss));
    if (newss == 0)
        return -1;

    yyss  = newss;
    yyssp = newss + i;
    newvs = (yyvs != 0)
          ? (YYSTYPE *)realloc(yyvs, newsize * sizeof(*newvs))
          : (YYSTYPE *)malloc(newsize * sizeof(*newvs));
    if (newvs == 0)
        return -1;

    yyvs = newvs;
    yyvsp = newvs + i;
    yystacksize = newsize;
    yysslim = yyss + newsize - 1;
    return 0;
}

#define YYABORT goto yyabort
#define YYREJECT goto yyabort
#define YYACCEPT goto yyaccept
#define YYERROR goto yyerrlab
int
yyparse(void)
{
    register int yym, yyn, yystate;
#if YYDEBUG
    register const char *yys;

    if ((yys = getenv("YYDEBUG")) != 0)
    {
        yyn = *yys;
        if (yyn >= '0' && yyn <= '9')
            yydebug = yyn - '0';
    }
#endif

    yynerrs = 0;
    yyerrflag = 0;
    yychar = YYEMPTY;

    if (yyss == NULL && yygrowstack()) goto yyoverflow;
    yyssp = yyss;
    yyvsp = yyvs;
    *yyssp = yystate = 0;

yyloop:
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
    if (yychar < 0)
    {
        if ((yychar = yylex()) < 0) yychar = 0;
#if YYDEBUG
        if (yydebug)
        {
            yys = 0;
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
            if (!yys) yys = "illegal-symbol";
            printf("%sdebug: state %d, reading %d (%s)\n",
                    YYPREFIX, yystate, yychar, yys);
        }
#endif
    }
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
    {
#if YYDEBUG
        if (yydebug)
            printf("%sdebug: state %d, shifting to state %d\n",
                    YYPREFIX, yystate, yytable[yyn]);
#endif
        if (yyssp >= yysslim && yygrowstack())
        {
            goto yyoverflow;
        }
        *++yyssp = yystate = yytable[yyn];
        *++yyvsp = yylval;
        yychar = YYEMPTY;
        if (yyerrflag > 0)  --yyerrflag;
        goto yyloop;
    }
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
    {
        yyn = yytable[yyn];
        goto yyreduce;
    }
    if (yyerrflag) goto yyinrecovery;

    yyerror("syntax error");

#ifdef lint
    goto yyerrlab;
#endif

yyerrlab:
    ++yynerrs;

yyinrecovery:
    if (yyerrflag < 3)
    {
        yyerrflag = 3;
        for (;;)
        {
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
            {
#if YYDEBUG
                if (yydebug)
                    printf("%sdebug: state %d, error recovery shifting\
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
#endif
                if (yyssp >= yysslim && yygrowstack())
                {
                    goto yyoverflow;
                }
                *++yyssp = yystate = yytable[yyn];
                *++yyvsp = yylval;
                goto yyloop;
            }
            else
            {
#if YYDEBUG
                if (yydebug)
                    printf("%sdebug: error recovery discarding state %d\n",
                            YYPREFIX, *yyssp);
#endif
                if (yyssp <= yyss) goto yyabort;
                --yyssp;
                --yyvsp;
            }
        }
    }
    else
    {
        if (yychar == 0) goto yyabort;
#if YYDEBUG
        if (yydebug)
        {
            yys = 0;
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
            if (!yys) yys = "illegal-symbol";
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
                    YYPREFIX, yystate, yychar, yys);
        }
#endif
        yychar = YYEMPTY;
        goto yyloop;
    }

yyreduce:
#if YYDEBUG
    if (yydebug)
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
                YYPREFIX, yystate, yyn, yyrule[yyn]);
#endif
    yym = yylen[yyn];
    if (yym)
        yyval = yyvsp[1-yym];
    else
        memset(&yyval, 0, sizeof yyval);
    switch (yyn)
    {
case 3:
#line 38 "parser.y"
{ insertStudent(yyvsp[0].student); }
break;
case 4:
#line 39 "parser.y"
{ insertStudent(yyvsp[0].student); }
break;
case 5:
#line 42 "parser.y"
{ yyval.student = insertNumber(yyvsp[-3].number,yyvsp[-1].student); }
break;
case 6:
#line 45 "parser.y"
{ yyval.student = insertName(yyvsp[-4].student,yyvsp[-1].string); }
break;
case 7:
#line 46 "parser.y"
{ yyval.student = insertAverage(yyvsp[-4].student,yyvsp[-1].number); }
break;
case 8:
#line 47 "parser.y"
{ yyval.student = insertType(yyvsp[-4].student,yyvsp[-1].tipo); }
break;
case 9:
#line 48 "parser.y"
{ yyval.student = insertYear(yyvsp[-4].student,yyvsp[-1].number); }
break;
case 10:
#line 49 "parser.y"
{ yyval.student = insertWanted(yyvsp[-4].student,yyvsp[-1].number); }
break;
case 11:
#line 50 "parser.y"
{ yyval.student = insertChoices(yyvsp[-4].student,yyvsp[-1].list); }
break;
case 12:
#line 51 "parser.y"
{ yyval.student = NULL; }
break;
case 13:
#line 54 "parser.y"
{ yyval.tipo = NORMAL; }
break;
case 14:
#line 55 "parser.y"
{ yyval.tipo = PROFESSIONAL; }
break;
case 15:
#line 56 "parser.y"
{ yyval.tipo = EXTRA; }
break;
case 16:
#line 60 "parser.y"
{ yyval.list = insertChoice(yyvsp[-4].list,yyvsp[-3].string,yyvsp[-1].number); }
break;
case 17:
#line 61 "parser.y"
{ yyval.list = NULL; }
break;
#line 546 "st.tab.c"
    }
    yyssp -= yym;
    yystate = *yyssp;
    yyvsp -= yym;
    yym = yylhs[yyn];
    if (yystate == 0 && yym == 0)
    {
#if YYDEBUG
        if (yydebug)
            printf("%sdebug: after reduction, shifting from state 0 to\
 state %d\n", YYPREFIX, YYFINAL);
#endif
        yystate = YYFINAL;
        *++yyssp = YYFINAL;
        *++yyvsp = yyval;
        if (yychar < 0)
        {
            if ((yychar = yylex()) < 0) yychar = 0;
#if YYDEBUG
            if (yydebug)
            {
                yys = 0;
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                if (!yys) yys = "illegal-symbol";
                printf("%sdebug: state %d, reading %d (%s)\n",
                        YYPREFIX, YYFINAL, yychar, yys);
            }
#endif
        }
        if (yychar == 0) goto yyaccept;
        goto yyloop;
    }
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
        yystate = yytable[yyn];
    else
        yystate = yydgoto[yym];
#if YYDEBUG
    if (yydebug)
        printf("%sdebug: after reduction, shifting from state %d \
to state %d\n", YYPREFIX, *yyssp, yystate);
#endif
    if (yyssp >= yysslim && yygrowstack())
    {
        goto yyoverflow;
    }
    *++yyssp = yystate;
    *++yyvsp = yyval;
    goto yyloop;

yyoverflow:
    yyerror("yacc stack overflow");

yyabort:
    return (1);

yyaccept:
    return (0);
}
